#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
    import PySimpleGUI as sg
else:
    import PySimpleGUI27 as sg
    sg.PopupError('This program uses Base64 images which are not supported in Python 2.7')
    sys.exit()
import datetime
import calendar
import forecastio

##### CHANGE these settings to match your location... check Google Maps #####
MY_LOCATION_LAT = 35.000000
MY_LOCATION_LON = -79.000000
##### You need a free dark-sky key. You get 1000 calls a month for free #####
DARKSKY_KEY =  "INSERT YOUR DARKSKY KEY HERE!"     # *** INSERT YOUR DARKSKY KEY HERE **

NUM_COLS = 5                    # Changes number of days in forecast


class GUI():
    def __init__(self):
        self.api_key = DARKSKY_KEY
        self.lat = MY_LOCATION_LAT
        self.lng = MY_LOCATION_LON
        self.blink_count = 0

        sg.SetOptions(border_width=0, text_color='white', background_color='black', text_element_background_color='black')

        # Create clock layout
        clock = [
            [sg.T('', pad=((120,0),0)),
             sg.Image(data=ledblank[22:], key='_hour1_'),
             sg.Image(data=ledblank[22:], key='_hour2_'),
             sg.Image(data=ledblank[22:], key='_colon_'),
             sg.Image(data=ledblank[22:], key='_min1_'),
             sg.Image(data=ledblank[22:], key='_min2_')], ]

        # Create the weather columns layout
        weather_cols = []
        for i in range(NUM_COLS):
            weather_cols.append(
                [[sg.T('', size=(4, 1), font='Any 20', justification='center', key='_DAY_' + str(i)), ],
                 [sg.Image(data=w1[22:], background_color='black', key='_icon_'+str(i), pad=((4, 0), 3)), ],
                 [sg.T('--', size=(3, 1), justification='center', font='Any 20', key='_high_' + str(i), pad=((10, 0), 3))],
                 [sg.T('--', size=(3, 1), justification='center', font='Any 20', key='_low_' + str(i), pad=((10, 0), 3))]])

        # Create the overall layout
        layout = [[sg.Column(clock, background_color='black')],
                  [sg.Column(weather_cols[x], background_color='black') for x in range(NUM_COLS)],

                  [sg.Button('Exit', button_color=('black', 'black'),
                              image_data=orangeround[22:], tooltip='close window', pad=((450,0),(10,0)))]]

        # Create the window
        self.window = sg.Window('My new window',
                           background_color='black',
                           grab_anywhere=True,
                           use_default_focus=False,
                           no_titlebar=True,
                           alpha_channel=.8,            # set an alpha channel if want transparent
                           ).Layout(layout).Finalize()

        self.colon_elem = self.window.FindElement('_colon_')
        self.hour1 = self.window.FindElement('_hour1_')
        self.hour2 = self.window.FindElement('_hour2_')
        self.min1 = self.window.FindElement('_min1_')
        self.min2 = self.window.FindElement('_min2_')


    def update_clock(self):
        # update the clock
        now = datetime.datetime.now()
        real_hour = now.hour - 12 if now.hour > 12 else now.hour
        hour1_digit = led_digits[real_hour // 10]
        self.hour1.Update(data=hour1_digit[22:])
        self.hour2.Update(data=led_digits[real_hour % 10][22:])
        self.min2.Update(data=led_digits[int(now.minute) % 10][22:])
        self.min1.Update(data=led_digits[int(now.minute) // 10][22:])
        # Blink the :
        if self.blink_count % 2:
            self.colon_elem.Update(data=ledcolon[22:])
        else:
            self.colon_elem.Update(data=ledblank[22:])
        self.blink_count += 1

    def update_weather(self):
        forecast = forecastio.load_forecast(self.api_key, self.lat, self.lng)
        daily = forecast.daily()
        today_weekday = datetime.datetime.today().weekday()

        max_temps = []
        min_temps = []
        daily_icons = []
        for daily_data in daily.data:
            daily_icons.append(daily_data.d['icon'])
            max_temps.append(int(daily_data.d['temperatureMax']))
            min_temps.append(int(daily_data.d['temperatureMin']))

        for i in range(NUM_COLS):
            day_element = self.window.FindElement('_DAY_' + str(i))
            max_element = self.window.FindElement('_high_' + str(i))
            min_element = self.window.FindElement('_low_' + str(i))
            icon_element = self.window.FindElement('_icon_' + str(i))
            day_element.Update(calendar.day_abbr[(today_weekday + i) % 7])
            max_element.Update(max_temps[i])
            min_element.Update(min_temps[i])
            icon_element.Update(data=weather_icon_dict[daily_icons[i]][22:])


def led_clock():

    # Get the GUI object that is used to update the window
    gui = GUI()

    # ---------- EVENT LOOP ----------
    last_update_time = 0
    while True:
        # Wake up once a second to update the clock and weather
        event, values = gui.window.Read(timeout=1000)
        if event in (None, 'Exit'):
            break
        # update clock
        gui.update_clock()
        # update weather once ever 6 hours
        now = datetime.datetime.now()
        if last_update_time == 0 or (now-last_update_time).seconds >= 60*60*6:
            print('*** Updating Weather ***')
            last_update_time = now
            gui.update_weather()


led0 = ''

led1 = ''

led2 = ''

led3 = ''

led4 = ''

led5 = ''

led6 = ''

led7 = ''

led8 = ''

led9 = ''

ledcolon = ''

ledblank = ''

w1 = ''

w2 = ''

w3 = ''

w4 = ''

w5 = ''

orangeround = ''

weather_icon_dict = {'clear-day': w1, 'clear-night': w1, 'rain': w3, 'snow': w3, 'sleet': w3, 'wind': w3, 'fog': w3,
                     'cloudy': w4, 'partly-cloudy-day': w5, 'partly-cloudy-night': w5}

led_digits = [led0, led1, led2, led3, led4, led5, led6, led7, led8, led9]

if __name__ == '__main__':
    led_clock()
